package com.fowo.api.service.handleWork;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.datainterface.constants.RequestMethodKind;
import com.fowo.api.datainterface.entity.DatainterfaceAuthority;
import com.fowo.api.datainterface.model.DataContextModel;
import com.fowo.api.datainterface.service.impl.implCore.LingxingServiceImpl;
import com.fowo.api.datainterface.service.DatainterfaceAuthorityService;
import com.fowo.api.datainterface.util.Common;
import com.fowo.api.datainterface.util.RestUtilLingXing;
import com.fowo.api.entity.Product;
import com.fowo.api.entity.Warehouse;
import com.fowo.api.model.stock.out.StockOutPushLingXingAction;
import com.fowo.api.model.stock.out.StockOutVo;
import com.fowo.api.model.stock.out.product.StockOutProductItemVo;
import com.fowo.api.service.impl.ProductServiceImpl;
import com.fowo.api.service.impl.ShopInfoServiceImpl;
import com.fowo.api.service.impl.StockOutServiceImpl;
import com.fowo.api.service.impl.WarehouseServiceImpl;
import com.fowo.api.util.LocalDateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class StockOutPushLingXing implements StockOutPushLingXingAction {
    private static final String STORAGE_ORDER_ADD_OUT = "https://openapi.lingxing.com" +
            "/erp/sc/routing/storage/storage/orderAddOut";
    @Resource
    private StockOutServiceImpl stockOutService;
    @Resource
    private WarehouseServiceImpl warehouseService;
    @Resource
    private ProductServiceImpl productService;
    @Resource
    private ShopInfoServiceImpl shopInfoService;
    @Resource
    private DatainterfaceAuthorityService datainterfaceAuthorityBaseService;
    @Resource
    private LingxingServiceImpl lingxingService;
    @Resource
    private RestUtilLingXing restUtilLingXing;
    @Override
    public void run(Long id) throws Exception {
        StockOutVo stockOutVo = stockOutService.getVoById(id);
        if (stockOutVo == null) {
            throw new Exception("出库单不存在");
        }
        if(stockOutVo.getIsPush() != null && stockOutVo.getIsPush()){
            throw new Exception("此单已推送领星");
        }
        Map<String, Object> requestBody = buildData(stockOutVo);
        Object res = push(requestBody);
        JSONObject result = JSONUtil.parseObj(res);
        if (result.getInt("code") != 0) {
            Assert.isTrue(false, "推送入库单失败，原因："+ result.getStr("error_details"));
        }
//        System.out.println("出库单号"+result.getJSONObject("data").getStr("order_sn"));
        stockOutVo.setIsPush(true);
        try {
            stockOutService.updateById(stockOutVo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 推送领星
     * @param requestBody
     */
    public Object push(Map<String, Object> requestBody){
        DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode, "Lingxing"), false);
        final DataContextModel.DatainterfaceAuthorityModel invoke = BeanUtil.copyProperties(entityAuthority, new DataContextModel().new DatainterfaceAuthorityModel().getClass());
        String accessToken = StrUtil.toStringOrNull(lingxingService.getAuth(invoke));
        String appId = Common.getAuthoritySimpleFactory(invoke, "appId");
        com.alibaba.fastjson.JSONObject params = new com.alibaba.fastjson.JSONObject();
        params.put("access_token", accessToken);
        params.put("app_key", appId);
        params.put("timestamp", System.currentTimeMillis() / 1000);
        Object res;
        try {
            res = restUtilLingXing.lingXingRequest("2", RequestMethodKind.Post.getValue(), params, STORAGE_ORDER_ADD_OUT, null, requestBody);
        } catch (Exception ex) {
            throw new RuntimeException(StrUtil.format("推送领星出库单发生异常 "));
        }
        return res;
    }

    /**
     * 构建数据
     * @param stockOutVo
     * @return
     */
    private Map<String, Object> buildData(StockOutVo stockOutVo) throws Exception {
        Map<String, Object> requestBody = new HashMap<>();
        final Warehouse warehouse = warehouseService.getById(stockOutVo.getWarehouse());
        requestBody.put("sys_wid",warehouse.getWid());
        int type = 0;
        switch (stockOutVo.getType()){
            case "CK003":
                type = 12;
                break;
            case "CK004":
                type = 14;
                break;
            default:
                throw new Exception("出库单类型必须为FBA出库或者退货出库");
        }
        requestBody.put("type",type);
        int status = 0;
        switch (stockOutVo.getStatus()){
            case "CS03":
                status = 10;
                break;
            case "CS02":
                status = 40;
                break;
            default:
                break;
        }
        requestBody.put("status",status);
//        final Supplier supplier = supplierService.getById(stockOutVo.getSupplier());
//        requestBody.put("sys_supplier_id",supplier.getSupplierCode());
//        requestBody.put("supplier_id",stockInVo.getSupplier().toString());
        if(StringUtils.isNotBlank(stockOutVo.getRemark()) ){
            requestBody.put("remark",stockOutVo.getRemark());
        }
        if(StringUtils.isNotBlank(stockOutVo.getTotalAmount())){
            String totalAmount = stockOutVo.getTotalAmount();
            BigDecimal bigDecimal = new BigDecimal(totalAmount);
            requestBody.put("return_price",bigDecimal);
        }
        final Warehouse towarehouse = warehouseService.getById(stockOutVo.getToWarehouse());
        if(towarehouse!=null){
            requestBody.put("sys_to_wid",towarehouse.getWid());
        }
        Date outTime = stockOutVo.getOutTime();
        if(outTime!=null){
            requestBody.put("outbound_time", LocalDateUtils.format(stockOutVo.getOutTime(),LocalDateUtils.DATE_PATTERN));
        }
        JSONArray array = new JSONArray();
        for(StockOutProductItemVo stockOutProductItemVo : stockOutVo.getStockOutProducts()){
            Long productId = stockOutProductItemVo.getProductId();
            Product product = productService.getById(productId);
            if (product == null) {
                throw new Exception("产品不存在");
            }
            JSONObject object = new JSONObject();
            object.putOpt("sku",stockOutProductItemVo.getSku());
            object.putOpt("good_num",stockOutProductItemVo.getProductGoodNum() == null ? 0 : stockOutProductItemVo.getProductGoodNum());
            object.putOpt("bad_num",stockOutProductItemVo.getProductBadNum() == null ? 0 : stockOutProductItemVo.getProductBadNum());
            object.putOpt("seller_id",stockOutProductItemVo.getSid() == null ? 0 : shopInfoService.getById(stockOutProductItemVo.getSid()).getShopCode());
            object.putOpt("fnsku",stockOutProductItemVo.getFnsku() == null ? "" : stockOutProductItemVo.getFnsku());
            array.add(object);
        }
        requestBody.put("product_list",array);
        return  requestBody;
    }
}
